﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using DiscreteEventModel.Common;

namespace DiscreteEventModelTest {

    public class MemoryMappedDictionaryTest : ITest {

        public class MyClass : IBinarySerializable, IEquatable<MyClass> {

            public int Data0;
            public double Data1;
            public long Data2;
            public double[] Data3;
            public string Data4;
            public decimal Data5;

            public MyClass(int data0, double data1, long data2, double[] data3, string data4, decimal data5) {
                this.Data0 = data0;
                this.Data1 = data1;
                this.Data2 = data2;
                this.Data3 = data3;
                this.Data4 = data4;
                this.Data5 = data5;
            }

            public MyClass() { }

            #region IBinarySerializable Members

            public void Serialize(IBinaryWriter writer) {
                writer.Write(this.Data0);
                writer.Write(this.Data1);
                writer.Write(this.Data2);
                writer.Write(this.Data3.Length);
                foreach(double d in this.Data3) {
                    writer.Write(d);
                }
                writer.Write(this.Data4.Length);
                for(int i = 0; i < this.Data4.Length; i++) {
                    writer.Write(this.Data4[i]);
                }
                writer.Write(this.Data5);

                Console.WriteLine("Serialized");
            }

            public void Deserialize(IBinaryReader reader) {
                this.Data0 = reader.ReadInt32();
                this.Data1 = reader.ReadDouble();
                this.Data2 = reader.ReadInt64();
                this.Data3 = new double[reader.ReadInt32()];
                for(int i = 0; i < this.Data3.Length; i++) {
                    this.Data3[i] = reader.ReadDouble();
                }
                char[] chars = new char[reader.ReadInt32()];
                for(int i = 0; i < chars.Length; i++) {
                    chars[i] = reader.ReadChar();
                }
                this.Data4 = new string(chars);
                this.Data5 = reader.ReadDecimal();

                Console.WriteLine("Deserialized");
            }

            #endregion

            #region IEquatable<MyClass> Members

            public bool Equals(MyClass other) {

                if(
                    this.Data0 == other.Data0 &&
                    this.Data1 == other.Data1 &&
                    this.Data2 == other.Data2 &&
                    this.Data3.Length == other.Data3.Length &&
                    this.Data4 == other.Data4 &&
                    this.Data5 == other.Data5) {

                    for(int i = 0; i < this.Data3.Length; i++) {
                        if(this.Data3[i] != other.Data3[i]) {
                            return false;
                        }
                    }
                }
                return true;
            }

            #endregion
        }

        #region ITest Members

        private Random rand = new Random();

        public void Run() {

            double value = 0.7d;
            byte[] bytes = BitConverter.GetBytes(value);
            Debug.Assert(BitConverter.ToDouble(bytes, 0) == value);

            int pageCapacity = 64;
            int maxPageCount = 1024 * 1024;
            int itemCount = 1024;

            Dictionary<int, MyClass> dict0 = new Dictionary<int, MyClass>();

            MemoryMappedDictionary<int, MyClass> dict1 = new MemoryMappedDictionary<int, MyClass>(new DirectoryInfo(@"C:\Users\Haymann\Documents\Temp"), new Guid(), pageCapacity, maxPageCount, () => { return new MyClass(); });

            for(int i = 0; i < itemCount; i++) {
                MyClass myClass = new MyClass(rand.Next(), rand.NextDouble(), (long)rand.Next(), new double[] { rand.NextDouble(), rand.NextDouble(), rand.NextDouble() }, "Hello world!", 7777777);
                dict0[i] = myClass;
                dict1[i] = myClass;
            }

            for(int i = 0; i < itemCount; i++) {
                if(!dict0[i].Equals(dict1[i])) {
                    throw new Exception();
                }
            }

            Console.ReadLine();
        }

        #endregion
    }
}
